home *** CD-ROM | disk | FTP | other *** search
- /*
- ** Copyright (C) 1991, 1997 Free Software Foundation, Inc.
- **
- ** This file is part of TACK.
- **
- ** TACK is free software; you can redistribute it and/or modify
- ** it under the terms of the GNU General Public License as published by
- ** the Free Software Foundation; either version 2, or (at your option)
- ** any later version.
- **
- ** TACK is distributed in the hope that it will be useful,
- ** but WITHOUT ANY WARRANTY; without even the implied warranty of
- ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- ** GNU General Public License for more details.
- **
- ** You should have received a copy of the GNU General Public License
- ** along with TACK; see the file COPYING. If not, write to
- ** the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- ** Boston, MA 02111-1307, USA.
- */
-
- #include <tack.h>
- #include <time.h>
-
- MODULE_ID("$Id: sync.c,v 1.3 2001/06/16 17:55:48 tom Exp $")
-
- /* terminal-synchronization and performance tests */
-
- static void sync_home(struct test_list *, int *, int *);
- static void sync_lines(struct test_list *, int *, int *);
- static void sync_clear(struct test_list *, int *, int *);
- static void sync_summary(struct test_list *, int *, int *);
-
- struct test_list sync_test_list[] = {
- {MENU_NEXT, 0, 0, 0, "b) baud rate test", sync_home, 0},
- {MENU_NEXT, 0, 0, 0, "l) scroll performance", sync_lines, 0},
- {MENU_NEXT, 0, 0, 0, "c) clear screen performance", sync_clear, 0},
- {MENU_NEXT, 0, 0, 0, "p) summary of results", sync_summary, 0},
- {0, 0, 0, 0, txt_longer_test_time, longer_test_time, 0},
- {0, 0, 0, 0, txt_shorter_test_time, shorter_test_time, 0},
- {MENU_LAST, 0, 0, 0, 0, 0, 0}
- };
-
- struct test_menu sync_menu = {
- 0, 'n', 0,
- "Performance tests", "perf", "n) run standard tests",
- sync_test, sync_test_list, 0, 0, 0
- };
-
- int tty_can_sync; /* TRUE if tty_sync_error() returned FALSE */
- int tty_newline_rate; /* The number of newlines per second */
- int tty_clear_rate; /* The number of clear-screens per second */
- int tty_cps; /* The number of characters per second */
-
- #define TTY_ACK_SIZE 64
-
- int ACK_terminator; /* terminating ACK character */
- int ACK_length; /* length of ACK string */
- const char *tty_ENQ; /* enquire string */
- char tty_ACK[TTY_ACK_SIZE]; /* ACK response, set by tty_sync_error() */
-
- /*****************************************************************************
- *
- * Terminal synchronization.
- *
- * These functions handle the messy business of enq-ack handshaking
- * for timing purposes.
- *
- *****************************************************************************/
-
- int
- tty_sync_error(void)
- {
- int ch, trouble, ack;
-
- trouble = FALSE;
- for (;;) {
- tt_putp(tty_ENQ); /* send ENQ */
- ch = getnext(STRIP_PARITY);
- event_start(TIME_SYNC); /* start the timer */
-
- /*
- The timer doesn't start until we get the first character.
- After that I expect to get the remaining characters of
- the acknowledge string in a short period of time. If
- that is not true then these characters are coming from
- the user and we need to send the ENQ sequence out again.
- */
- for (ack = 0; ; ) {
- if (ack < TTY_ACK_SIZE - 2) {
- tty_ACK[ack] = ch;
- tty_ACK[ack + 1] = '\0';
- }
- if (ch == ACK_terminator) {
- return trouble;
- }
- if (++ack >= ACK_length) {
- return trouble;
- }
- ch = getnext(STRIP_PARITY);
- if (event_time(TIME_SYNC) > 400000) {
- break;
- }
- }
-
- set_attr(0); /* just in case */
- put_crlf();
- if (trouble) {
- /* The terminal won't sync. Life is not good. */
- return TRUE;
- }
- put_str(" -- sync -- ");
- trouble = TRUE;
- }
- }
-
- /*
- ** flush_input()
- **
- ** Throw away any output.
- */
- void
- flush_input(void)
- {
- if (tty_can_sync == SYNC_TESTED && ACK_terminator >= 0) {
- (void) tty_sync_error();
- } else {
- spin_flush();
- }
- }
-
- /*
- ** probe_enq_ok()
- **
- ** does the terminal do enq/ack handshaking?
- */
- static void
- probe_enq_ok(void)
- {
- int tc, len, ulen;
-
- put_str("Testing ENQ/ACK, standby...");
- fflush(stdout);
- can_test("u8 u9", FLAG_TESTED);
-
- #ifdef user9
- tty_ENQ = user9 ? user9 : "\005";
- #else
- tty_ENQ = "\005";
- #endif
- tc_putp(tty_ENQ);
- event_start(TIME_SYNC); /* start the timer */
- read_key(tty_ACK, TTY_ACK_SIZE - 1);
-
- if (event_time(TIME_SYNC) > 400000 || tty_ACK[0] == '\0') {
- /* These characters came from the user. Sigh. */
- tty_can_sync = SYNC_FAILED;
- ptext("\nThis program expects the ENQ sequence to be");
- ptext(" answered with the ACK character. This will help");
- ptext(" the program reestablish synchronization when");
- ptextln(" the terminal is overrun with data.");
- ptext("\nENQ sequence from (u9): ");
- putln(expand(tty_ENQ));
- ptext("ACK received: ");
- putln(expand(tty_ACK));
- #ifdef user8
- len = user8 ? strlen(user8) : 0;
- #else
- len = 0;
- #endif
- sprintf(temp, "Length of ACK %d. Expected length of ACK %d.",
- (int) strlen(tty_ACK), len);
- ptextln(temp);
- #ifdef user8
- if (len) {
- temp[0] = user8[len - 1];
- temp[1] = '\0';
- ptext("Terminating character found in (u8): ");
- putln(expand(temp));
- }
- #endif
- return;
- }
-
- tty_can_sync = SYNC_TESTED;
- if ((len = strlen(tty_ACK)) == 1) {
- /* single character acknowledge string */
- ACK_terminator = tty_ACK[0];
- ACK_length = 4096;
- return;
- }
- tc = tty_ACK[len - 1];
- #ifdef user8
- if (user8) {
- ulen = strlen(user8);
- if (tc == user8[ulen - 1]) {
- /* ANSI style acknowledge string */
- ACK_terminator = tc;
- ACK_length = 4096;
- return;
- }
- }
- #endif
- /* fixed length acknowledge string */
- ACK_length = len;
- ACK_terminator = -2;
- }
-
- /*
- ** verify_time()
- **
- ** verify that the time tests are ready to run.
- ** If the baud rate is not set then compute it.
- */
- void
- verify_time(void)
- {
- int status, ch;
-
- if (tty_can_sync == SYNC_FAILED) {
- return;
- }
- probe_enq_ok();
- put_crlf();
- if (tty_can_sync == SYNC_TESTED) {
- put_crlf();
- if (ACK_terminator >= 0) {
- ptext("ACK terminating character: ");
- temp[0] = ACK_terminator;
- temp[1] = '\0';
- ptextln(expand(temp));
- } else {
- sprintf(temp, "Fixed length ACK, %d characters",
- ACK_length);
- ptextln(temp);
- }
- }
- if (tty_baud_rate == 0) {
- sync_home(&sync_test_list[0], &status, &ch);
- }
- }
-
- /*****************************************************************************
- *
- * Terminal performance tests
- *
- * Find out how fast the terminal can:
- * 1) accept characters
- * 2) scroll the screen
- * 3) clear the screen
- *
- *****************************************************************************/
-
- /*
- ** sync_home(test_list, status, ch)
- **
- ** Baudrate test
- */
- void
- sync_home(
- struct test_list *t,
- int *state,
- int *ch)
- {
- int j, k;
- unsigned long rate;
-
- if (!cursor_home && !cursor_address && !row_address) {
- ptext("Terminal can not home cursor. ");
- generic_done_message(t, state, ch);
- return;
- }
- if (skip_pad_test(t, state, ch,
- "(home) Start baudrate search")) {
- return;
- }
- pad_test_startup(1);
- do {
- go_home();
- for (j = 1; j < lines; j++) {
- for (k = 0; k < columns; k++) {
- if (k & 0xF) {
- put_this(letter);
- } else {
- put_this('.');
- }
- }
- SLOW_TERMINAL_EXIT;
- }
- NEXT_LETTER;
- } while(still_testing());
- pad_test_shutdown(t, auto_right_margin == 0);
- /* note: tty_frame_size is the real framesize times two.
- This takes care of half bits. */
- rate = (tx_cps * tty_frame_size) >> 1;
- if (rate > tty_baud_rate) {
- tty_baud_rate = rate;
- }
- if (tx_cps > tty_cps) {
- tty_cps = tx_cps;
- }
- sprintf(temp, "%d characters per second. Baudrate %d ", tx_cps, j);
- ptext(temp);
- generic_done_message(t, state, ch);
- }
-
- /*
- ** sync_lines(test_list, status, ch)
- **
- ** How many newlines/second?
- */
- static void
- sync_lines(
- struct test_list *t,
- int *state,
- int *ch)
- {
- int j;
-
- if (skip_pad_test(t, state, ch,
- "(nel) Start scroll performance test")) {
- return;
- }
- pad_test_startup(0);
- repeats = 100;
- do {
- sprintf(temp, "%d", test_complete);
- put_str(temp);
- put_newlines(repeats);
- } while(still_testing());
- pad_test_shutdown(t, 0);
- j = sliding_scale(tx_count[0], 1000000, usec_run_time);
- if (j > tty_newline_rate) {
- tty_newline_rate = j;
- }
- sprintf(temp, "%d linefeeds per second. ", j);
- ptext(temp);
- generic_done_message(t, state, ch);
- }
-
- /*
- ** sync_clear(test_list, status, ch)
- **
- ** How many clear-screens/second?
- */
- static void
- sync_clear(
- struct test_list *t,
- int *state,
- int *ch)
- {
- int j;
-
- if (!clear_screen) {
- ptext("Terminal can not clear-screen. ");
- generic_done_message(t, state, ch);
- return;
- }
- if (skip_pad_test(t, state, ch,
- "(clear) Start clear-screen performance test")) {
- return;
- }
- pad_test_startup(0);
- repeats = 20;
- do {
- sprintf(temp, "%d", test_complete);
- put_str(temp);
- for (j = 0; j < repeats; j++) {
- put_clear();
- }
- } while(still_testing());
- pad_test_shutdown(t, 0);
- j = sliding_scale(tx_count[0], 1000000, usec_run_time);
- if (j > tty_clear_rate) {
- tty_clear_rate = j;
- }
- sprintf(temp, "%d clear-screens per second. ", j);
- ptext(temp);
- generic_done_message(t, state, ch);
- }
-
- /*
- ** sync_summary(test_list, status, ch)
- **
- ** Print out the test results.
- */
- static void
- sync_summary(
- struct test_list *t,
- int *state,
- int *ch)
- {
- char size[32];
-
- put_crlf();
- ptextln("Terminal size characters/sec linefeeds/sec clears/sec");
- sprintf(size, "%dx%d", columns, lines);
- sprintf(temp, "%-10s%-11s%11d %11d %11d", tty_basename, size,
- tty_cps, tty_newline_rate, tty_clear_rate);
- ptextln(temp);
- generic_done_message(t, state, ch);
- }
-
- /*
- ** sync_test(menu)
- **
- ** Run at the beginning of the pad tests and function key tests
- */
- void
- sync_test(
- struct test_menu *menu)
- {
- control_init();
- if (tty_can_sync == SYNC_NOT_TESTED) {
- verify_time();
- }
- if (menu->menu_title) {
- put_crlf();
- ptextln(menu->menu_title);
- }
- }
-
- /*
- ** sync_handshake(test_list, status, ch)
- **
- ** Test or retest the ENQ/ACK handshake
- */
- void
- sync_handshake(
- struct test_list *t GCC_UNUSED,
- int *state GCC_UNUSED,
- int *ch GCC_UNUSED)
- {
- tty_can_sync = SYNC_NOT_TESTED;
- verify_time();
- }
-